//change int in speed to float, add setSpeed to Lane, remove speed from nest

#include "GUINest.h"
#include "Part.h"

/**
 * @fn	GUINest::GUINest(int X, int Y,int capacity,QGraphicsScene *scene)
 *
 * @brief	Constructor.
 *
 * @author	Ben White
 *
 * @param	X			 	The X coordinate.
 * @param	Y			 	The Y coordinate.
 * @param	capacity	 	The capacity.
 * @param [in,out]	scene	If non-null, the scene.
 */


GUINest::GUINest(int startX, int startY, NestColor nestColor)
	: GUIBase()

{
	switch (nestColor)
	{
		case NestColor_Yellow: loadImage("Resources/Sprites/Nest/Nest1.png"); break;
		case NestColor_Purple: loadImage("Resources/Sprites/Nest/Nest2.png"); break;
		case NestColor_Green: loadImage("Resources/Sprites/Nest/Nest3.png"); break;
		case NestColor_Red: loadImage("Resources/Sprites/Nest/Nest4.png"); break;
	}
	srand(0);
	Running=false;
	Purging=false;
	Broken=false;
	this->setX(startX);
	this->setY(startY);
	this->setZValue(ZVALUE_NEST);
	//moveTo(x(),y());
	NumberOfParts=0;
	PartSize=12;
	Capacity=9;
	PartsIn1=PartsIn2=PartsIn3=0;
	for(int ii=0 ; ii<3 ; ii++)
	{
		for(int jj=0 ; jj<3 ; jj++)
		{
			PartsInNest[ii][jj]=NULL;
		}
	}
}

/**
 * @fn	void GUINest::Start(int speed)
 *
 * @brief	Starts.
 *
 * @author	Ben White
 *
 * @param	speed	The speed.
 */

void GUINest::Start()
{
	if(!Broken)
	{
		Running=true;
	}
}

/**
 * @fn	void GUINest::Stop()
 *
 * @brief	Stops this object.
 *
 * @author	Ben White
 */

void GUINest::Stop()
{
	Running=false;
}

void GUINest::setBroken(bool isBroken)
{
	Broken=isBroken;
	if(Broken)
	{
		this->Stop();
	}
	else
	{
		this->Start();
	}
}

/**
 * @fn	void GUINest::DoBreak()
 *
 * @brief	Executes the break operation.
 *
 * @author	Ben White
 */

void GUINest::DoBreak()
{
	GUIBase::DoBreak();
	Broken=true;
	this->Stop();
}

/**
 * @fn	void GUINest::DoFix()
 *
 * @brief	Executes the fix operation.
 *
 * @author	Ben White
 */

void GUINest::DoFix()
{
	GUIBase::DoFix();
	Broken=false;
	this->Start();
}
/**
 * @fn	void GUINest::setPurge(bool purge)
 *
 * @brief	Sets a purge.
 *
 * @author	Ben White
 *
 * @param	purge	true to purge.
 */

void GUINest::setPurge(bool purge)
{
	Purging=purge;
}

void GUINest::togglePurge()
{
	Purging=!Purging;
}

/**
 * @fn	Part* GUINest::getPart(void)
 *
 * @brief	Gets the part.
 *
 * @author	Ben White
 *
 * @return	null if it fails, else the part.
 */

Part* GUINest::getPart(void)
{
	//qDebug() << "GUINEST: getPart called";
	Part* Temp=PartsInNest[0][0];
	if(Temp!=NULL && NumberOfParts==Capacity)//if the first part is not NULL and the Nest is full
	{
		PartsInNest[0][0]=NULL;//removes the reference to the first part from the array
		NumberOfParts--;//decriments number of parts

		////////////////////////////////////
		PartsIn3--;//decriments the number parts in the 3rd row
		PartsInNest[0][0]=PartsInNest[1][0];//shift a part from row 2 to row 1
		PartsInNest[1][0]=PartsInNest[2][0];//shift a part from row 3 to row 2
		PartsInNest[2][0]=NULL;//remove the reference to the shifted part from row 3
		////////////////////////////////////
		/*if(PartsIn2>0)//this is an old implementation of parts shifting left after a part is removed
		{
			for(int ii=0 ; ii<3 ; ii++)
			{
				if(PartsInNest[1][ii]!=NULL)
				{
					PartsInNest[0][0]=PartsInNest[1][ii];
					PartsInNest[1][ii]=NULL;
					PartsIn2--;
					for(int jj=0 ; jj<3 ; jj++)
					{
						if(PartsInNest[2][jj]==NULL)
						{
							PartsInNest[1][ii]=PartsInNest[2][jj];
							PartsInNest[2][jj]=NULL;
							PartsIn2++;
							PartsIn3--;
							break;
						}
					}
					break;
				}
			}
		}
		else
		{
			PartsIn1--;
		}*/
		
		return Temp;
	}
	return NULL;
}

bool GUINest::givePart(Part* P)//attempts to give a part to the nest
{
	//qDebug()<<"GUINest: Giving Nest Part..."<<P<<endl;
	P->setParentItem(NULL);//removes the parent reference to ensure part uses scene coordinates
	if(NumberOfParts<Capacity && !Broken)//if there is room in the nest
	{
		if(PartsIn1<3)//if there is room in the first row
		{
			for(int ii=0 ; ii<3 ; ii++)//loop through the first row to find an empty spot
			{
				if(PartsInNest[0][ii]==NULL)
				{
					PartsInNest[0][ii]=P;//place the part in the empty spot
					NumberOfParts++;//increment counters
					PartsIn1++;
					/*if(PartsInNest[0][ii]==NULL)
					{
						//qDebug("GUINest: I got passed a NULL");
					}*/
					//qDebug("GUINest: Part Given 1");
					
					return true;//tell lane part was taken
				}
			}
		}
		else if(PartsIn2<3)//if there is room in the second row
		{
			for(int ii=0 ; ii<3 ; ii++)//loop through the second row
			{
				if(PartsInNest[1][ii]==NULL)
				{
					PartsInNest[1][ii]=P;//place part in second row
					NumberOfParts++;//increment counter
					PartsIn2++;
					//qDebug("GUINest: Part Given 2");
					return true;//tell lane part was taken
				}
			}
		}
		else if(PartsIn3<3)//if there is room in the third row
		{
			for(int ii=0 ; ii<3 ; ii++)//loop through until an empty spot is taken
			{
				if(PartsInNest[2][ii]==NULL)
				{
					PartsInNest[2][ii]=P;//place part in third row
					NumberOfParts++;//increment counters
					PartsIn3++;
					//qDebug("GUINest: Part Given 3");
					return true;//tell lane part was taken
				}
			}
		}
	}
	//qDebug("GUINest: Part not Given");
	return false;//tell lane part was not taken
}

void GUINest::advance(int phase)
{
	
	if(phase==1 && Running && !Purging)
	{	////////////////////////////////////////////////////////////////////////////
		//					Provide unstable nest animation						  //
		////////////////////////////////////////////////////////////////////////////
		if(PartsIn1<3 && PartsIn1>0)//if first row is not empty and not full
		{
			for(int ii=0 ; ii<3 ; ii++)//loop through the row
			{
				if(PartsInNest[0][ii]!=NULL)//if a spot is not empty
				{   //qDebug("Part Shifting Nest");
					if(PartsInNest[0][(ii+5)%3]==NULL)//grap that part and attempt to shift it
					{
						PartsInNest[0][(ii+5)%3]=PartsInNest[0][ii];//if (ii+5)%3 is not occupied place part ii there
						PartsInNest[0][ii]=NULL;
						break;
					}
					//qDebug("Part Shifted Nest");
				}
			}
		}
		else if(PartsIn2<3 && PartsIn2>0)//if row 2 is not empty and not full
		{
			for(int ii=0 ; ii<3 ; ii++)//loop through until a part is found
			{
				if(PartsInNest[1][ii]!=NULL)
				{
					if(PartsInNest[1][(ii+5)%3]==NULL)
					{
						PartsInNest[1][(ii+5)%3]=PartsInNest[1][ii];//attempt to shift it
						PartsInNest[1][ii]=NULL;
						break;
					}
				}
			}
		}
		else if(PartsIn3<3 && PartsIn3>0)//if the third row is not empty and not full
		{
			for(int ii=0 ; ii<3 ; ii++)//loop until a part is found
			{
				if(PartsInNest[2][ii]!=NULL)
				{
					if(PartsInNest[2][(ii+5)%3]==NULL)
					{
						PartsInNest[2][(ii+5)%3]=PartsInNest[2][ii];//attempt to shift it
						PartsInNest[2][ii]=NULL;
						break;
					}
				}
			}
		}
		////////////////////////////////////////////////////////
		//Go through and set x and y according to nest indeces//
		////////////////////////////////////////////////////////
		
		//std::cerr<<"Part Moving \n";
		for (int ii=0 ; ii<3 ; ii++)
		{
			for(int jj=0 ; jj<3; jj++)
			{	//qDebug("Part Moving Nest");
				if(PartsInNest[ii][jj]!=NULL)
				{	//qDebug("Part Moving Nest");
					//qDebug()<<PartsInNest[ii][jj];
					//qDebug()<<this;
					PartsInNest[ii][jj]->setX((this->x())+5+ii*PartSize+(PartSize/2));
					PartsInNest[ii][jj]->setY((this->y())+5+(PartSize*jj)+(PartSize/2));
				}
			}
		}
		/*
		for(int jj=0 ; jj<3 ; jj++)
		{	
			if(PartsInNest[0][jj]!=NULL)
			{
				PartsInNest[0][jj]->setX((this->x())+5+(PartSize/2));
				PartsInNest[0][jj]->setY((this->y())+5+(PartSize*jj)+(PartSize/2));
				//qDebug("Part Moved Nest");
			}
			
		}
		for(int jj=0 ; jj<3; jj++)
		{	//qDebug("Part Moving Nest");
			if(PartsInNest[1][jj]!=NULL)
			{	//qDebug("Part Moving Nest");
				//qDebug()<<PartsInNest[1][jj];
				//qDebug()<<this;
				PartsInNest[1][jj]->setX((this->x())+5+PartSize+(PartSize/2));
				PartsInNest[1][jj]->setY((this->y())+5+(PartSize*jj)+(PartSize/2));
			}
			
		}
		for(int jj=0 ; jj<3; jj++)
		{	//qDebug("Part Moving Nest");
			if(PartsInNest[2][jj]!=NULL)
			{//qDebug("Part Moving Nest");
			//qDebug()<<PartsInNest[2][jj];
			PartsInNest[2][jj]->setX((this->x())+5+(PartSize*2)+(PartSize/2));
			PartsInNest[2][jj]->setY((this->y())+5+(PartSize*jj)+(PartSize/2));
			//qDebug("Part Moved Nest");
			}
			
		}
		*/
		//std::cerr<<"Part Moved \n";
	}//phase==1 && Running && !Purging
	///////////////////////////////////////////////////////
	//					Purging stuff					 //
	///////////////////////////////////////////////////////
	if(phase==1 && Purging)
	{
		for(int ii=0 ; ii<3 ; ii++)
		{
			if(PartsInNest[0][ii]!=NULL)
			{
				PurgePart(PartsInNest[0][ii]);//temporary purge implementation
				PartsInNest[0][ii]=NULL;
				PartsIn1--;
				NumberOfParts--;
			}
		}
		for(int ii=0 ; ii<3 ; ii++)
		{
			if(PartsInNest[1][ii]!=NULL)
			{
				PurgePart(PartsInNest[1][ii]);//temporary purge implementation
				PartsInNest[1][ii]=NULL;
				PartsIn2--;
				NumberOfParts--;
			}
		}//animation to be added for V2
		for(int ii=0 ; ii<3 ; ii++)
		{
			if(PartsInNest[2][ii]!=NULL)
			{
				PurgePart(PartsInNest[2][ii]);//temporary purge implementation
				PartsInNest[2][ii]=NULL;
				PartsIn3--;
				NumberOfParts--;
			}
		}//animation to be added for V2
	
	}
}//advance

void GUINest::PurgePart(Part* P)
{
	P->speed=P->speed*2;
	P->moveTo(P->x()+((std::rand()%25)-100),P->y()+((std::rand()%50)-25));
	P->PartFellOnFloor();
}

